#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_system.h"
#include "esp_log.h"
#include "lvgl.h"
#include "esp_lcd_panel_ops.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_lcd_types.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_timer.h"
#include "esp_err.h"
#include "hardware.h"
#include "lcd.h"
#include "touch.h"
#include "agriculture_ui.h"
#include "esp_lvgl_port.h"

#define TAG "DEMO"

// 屏幕尺寸 - 横屏模式
#define SCREEN_WIDTH  LCD_H_RES
#define SCREEN_HEIGHT LCD_V_RES

int screen_width = SCREEN_WIDTH;
int screen_height = SCREEN_HEIGHT;

// 创建UI（使用农业监测UI模块）
void create_ui(void)
{
    ESP_LOGI(TAG, "开始创建农业监测系统UI...");
    
    // 添加内存检查
    ESP_LOGI(TAG, "创建UI前 - 可用内存: %u bytes", (unsigned int)esp_get_free_heap_size());
    
    // 调用农业监测UI创建函数
    create_agriculture_ui();
    
    ESP_LOGI(TAG, "创建UI后 - 可用内存: %u bytes", (unsigned int)esp_get_free_heap_size());
    ESP_LOGI(TAG, "农业监测系统UI创建完成");
}

static void read_touch_data_task(void *pvParameters)
{
    ESP_LOGI(TAG, "触摸数据读取任务已启动");
    esp_lcd_touch_handle_t tp = (esp_lcd_touch_handle_t)pvParameters;
    uint16_t touch_x = 0, touch_y = 0;
    uint8_t touch_cnt = 0;
    bool touched = false;                                                                                                                                  
    uint32_t last_touch_time = 0;
    int count = 0;
    
    while (1) {
        count++;
        if (count % 500 == 0) { // 每5秒输出一次调试信息
            ESP_LOGI(TAG, "触摸数据读取任务运行中，触摸控制器: %p", tp);
        }
        
        // 检查触摸控制器是否有效
        if (!tp) {
            ESP_LOGE(TAG, "触摸控制器指针无效");
            vTaskDelay(100 / portTICK_PERIOD_MS); // 无效时增加延迟
            continue;
        }
        
        // 读取触摸状态
        esp_err_t ret = esp_lcd_touch_read_data(tp);
        if (ret != ESP_OK) {
            ESP_LOGE(TAG, "读取触摸数据失败: %d", ret);
            vTaskDelay(10 / portTICK_PERIOD_MS);
            continue;
        }
        
        // 获取触摸点信息
        touched = esp_lcd_touch_get_coordinates(tp, &touch_x, &touch_y, NULL, &touch_cnt, 1);
        
        if (touched && touch_cnt > 0) {
            uint32_t current_time = esp_timer_get_time() / 1000; // 毫秒
            // 只有当触摸状态变化或时间间隔超过50ms时才打印日志，避免日志过多
            if (current_time - last_touch_time > 50) {
                ESP_LOGI("TOUCH", "检测到触摸! X=%d, Y=%d, 点数=%d", touch_x, touch_y, touch_cnt);
                last_touch_time = current_time;
            }
        }
        
        vTaskDelay(10 / portTICK_PERIOD_MS); // 10ms检测一次
    }
}

void app_main(void)
{
    esp_lcd_panel_io_handle_t lcd_io = NULL;
    esp_lcd_panel_handle_t lcd_panel = NULL;
    esp_lcd_touch_handle_t tp = NULL;
    lv_display_t *lvgl_display = NULL;
    lv_indev_t *touch_indev = NULL;
    
    ESP_LOGI(TAG, "开始初始化LCD测试...");
    
    // 初始化硬件 - 暂时注释掉LEDC背光控制，使用直接的GPIO控制
    // ESP_ERROR_CHECK(lcd_display_brightness_init());
    
    // 直接使用GPIO方式控制背光 - 更简单可靠
    ESP_LOGI(TAG, "使用GPIO直接控制LCD背光 - GPIO_NUM_21");
    gpio_config_t backlight_config = {
        .pin_bit_mask = (1ULL << LCD_BACKLIGHT),
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_DISABLE
    };
    ESP_ERROR_CHECK(gpio_config(&backlight_config));
    ESP_ERROR_CHECK(gpio_set_level(LCD_BACKLIGHT, 1));  // 直接打开背光
    ESP_LOGI(TAG, "LCD背光已打开");
    
    // 初始化LCD
    ESP_LOGI(TAG, "初始化LCD...");
    ESP_ERROR_CHECK(app_lcd_init(&lcd_io, &lcd_panel));
    ESP_LOGI(TAG, "LCD初始化完成");
    
    // 初始化LVGL
    ESP_LOGI(TAG, "初始化LVGL...");
    lvgl_display = app_lvgl_init(lcd_io, lcd_panel);
    if (lvgl_display == NULL) {
        ESP_LOGE(TAG, "LVGL初始化失败");
        esp_restart();
    }
    
    // 使用LVGL端口锁保护与LVGL相关的API调用
    if (lvgl_port_lock(portMAX_DELAY)) {
        // 设置显示方向为90度，确保与镜像配置一致
        ESP_ERROR_CHECK(lcd_display_rotate(lvgl_display, LV_DISPLAY_ROTATION_90)); // 启用横屏显示
        ESP_LOGI(TAG, "显示方向配置完成：横屏模式");

        ESP_LOGI(TAG, "LVGL初始化完成");

        // 隐藏LVGL性能监控显示
        extern void lv_sysmon_hide_performance(lv_display_t * disp);
        lv_sysmon_hide_performance(lvgl_display);
        ESP_LOGI(TAG, "性能监控显示已隐藏");

        // 创建测试UI
        ESP_LOGI(TAG, "创建测试UI...");
        create_ui();
        
        // 注意：初始化阶段不进行全屏强制刷新，避免潜在崩溃
        // 如果需要刷新，请依赖LVGL任务的正常调度或在安全的时机触发

        lvgl_port_unlock();
    } else {
        ESP_LOGE(TAG, "无法获取LVGL端口锁，LVGL相关初始化可能不安全");
    }
    
    // 初始化触摸屏
    ESP_LOGI(TAG, "初始化触摸屏...");
    ESP_ERROR_CHECK(touch_init(&tp));
    ESP_LOGI(TAG, "触摸屏初始化完成，绑定到LVGL输入设备...");
    const lvgl_port_touch_cfg_t touch_cfg = {
        .disp = lvgl_display,
        .handle = tp,
        // 可按需设置缩放：.scale = { .x = 1.0f, .y = 1.0f },
    };
    touch_indev = lvgl_port_add_touch(&touch_cfg);
    if (touch_indev == NULL) {
        ESP_LOGE(TAG, "LVGL触摸输入设备绑定失败");
    } else {
        ESP_LOGI(TAG, "LVGL触摸输入设备绑定成功");
    }
    
    ESP_LOGI(TAG, "测试UI已创建，开始渲染循环...");
    
    // 主循环 - 只负责更新农业数据，LVGL任务由专门的线程处理
    while(1) {
        // 仅更新农业数据，避免与LVGL任务冲突
        if (lvgl_port_lock(0)) {
            update_agriculture_ui();
            lvgl_port_unlock();
        }
        
        // 增加较长的延迟时间，给IDLE任务更多机会运行以复位看门狗
        // 农业数据不需要频繁更新，这样可以降低系统资源占用
        vTaskDelay(500 / portTICK_PERIOD_MS);  // 500ms更新一次数据
    }
}
